//
//  BirthdayAppendTableViewImplement.swift
//  FearfulNotification
//
//  Created by Jabin on 2019/6/2.
//  Copyright © 2019 筱鹏. All rights reserved.
//

import UIKit

class BirthdayAppendData {
    enum DataType {
        case date
        case name
        case desc
    }
    var type: DataType
    var alertClosure: (Bool)->Void = {_ in}
    var textClosure: (String)->Void = {_ in}
    
    var month: Int = 0
    var day: Int = 0
    
    var name: String = ""
    
    var desc: String = ""
    
    var alert: Bool = false
    
    var height: CGFloat = 0
    
    init(type: DataType) {
        self.type = type
    }
}

class BirthdayAppendTableViewImplement: NSObject {
    
    let DatePickerCellId: String = "datePickerCellId"
    let AppendCellId: String = "appendCellId"
    
    enum FunctionType {
        case edit
        case add
    }
    var functionType: FunctionType = .add
    var birthdayId: Int64 = 0
    
    var datas: [BirthdayAppendData] = []
    var currentEntity: BirthdayEntity?
    var tableView: UITableView!
    
    convenience init(tableView: UITableView, birthdayId: Int64?) {
        self.init()
        setup(tableView: tableView)
        setup(birthdayId: birthdayId)
    }
    
    private func setup(tableView view: UITableView) {
        tableView = view
        tableView.delegate = self
        tableView.dataSource = self
        
        tableView.register(BirthdayDatePicker.self, forCellReuseIdentifier: DatePickerCellId)
        tableView.register(BirthdayAppendCell.self, forCellReuseIdentifier: AppendCellId)
    }
    
    private func setup(birthdayId bId: Int64?) {
        if let birthdayId = bId {
            functionType = .edit
            self.birthdayId = birthdayId
            setupEditDatas()
        } else {
            functionType = .add
            birthdayId = BirthdayRelatedInfo.obtainBirthdayId()
            setupAddDatas()
        }
    }
    
    private func setupAddDatas() {
        let dateData = BirthdayAppendData(type: .date)
        dateData.month = 1
        dateData.day = 1
        dateData.height = 200

        let nameData = BirthdayAppendData(type: .name)
        nameData.height = 50

        let descData = BirthdayAppendData(type: .desc)
        descData.height = 50

        datas = [dateData, nameData, descData]
    }
    
    private func setupEditDatas() {
        let entitys = BirthdayEntity.execute.fetch("birthdayId='\(birthdayId)'")
        guard let entity = entitys.first else {
            setupAddDatas()
            return
        }
        currentEntity = entity
        
        let dateData = BirthdayAppendData(type: .date)
        dateData.month = Int(entity.birthdayMonth)
        dateData.day = Int(entity.birthdayDay)
        dateData.height = 200
        
        let nameData = BirthdayAppendData(type: .name)
        nameData.name = entity.name ?? ""
        nameData.height = 50
        
        let descData = BirthdayAppendData(type: .desc)
        descData.desc = entity.desc ?? ""
        descData.height = 50
        
        datas = [dateData, nameData, descData]
        
    }
    
    func saveBirthday(_ finish: @escaping (Bool) -> Void) {
        switch functionType {
        case .add:
            BirthdayRelatedInfo.updateBirthdayId()
            BirthdayEntity.execute.insert({ (success) in
                self.setupEntityAlert({ (success) in
                    finish(success)
                })
            }) { (entity) in
                self.configEntityValue(entity)
            }
            break
            
        case .edit:
            currentEntity?.execute.change({ (success) in
                self.setupEntityAlert({ (success) in
                    finish(success)
                })
            }, { (entity) in
                self.configEntityValue(entity)
            })
        }
    }
    
    private func setupEntityAlert(_ finish: @escaping (Bool) -> Void) {
        let entitys = BirthdayEntity.execute.fetch("birthdayId='\(birthdayId)'")
        guard let entity = entitys.first else { return }
        entity.configAlertAndChangeStatus(true) { (status) in
            Event.message("status \(status)")
            finish(true)
        }
    }
    
    private func configEntityValue(_ entity: BirthdayEntity) {
        entity.birthdayId = birthdayId
        datas.forEach { (obj) in
            switch obj.type {
            case .name:
                entity.name = obj.name
                break
            case .date:
                entity.birthdayMonth = Int16(obj.month)
                entity.birthdayDay = Int16(obj.day)
                break
            case .desc:
                entity.desc = obj.desc
                break
            }
        }
    }
}

extension BirthdayAppendTableViewImplement: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return datas.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let data = datas[indexPath.row]
        var cell: UITableViewCell? = nil;
        switch data.type {
        case .name:
            let nameCell = tableView.dequeueReusableCell(withIdentifier: AppendCellId,
                                                         for: indexPath) as! BirthdayAppendCell
            nameCell.config(with: "姓名", type: .isTextField)
            nameCell.textField.text = data.name
            nameCell.textFiledClosure = { name in
                data.name = name
            }
            cell = nameCell
            break
        case .date:
            let dateCell = tableView.dequeueReusableCell(withIdentifier: DatePickerCellId,
                                                         for: indexPath) as! BirthdayDatePicker
            dateCell.configDate(data.month, data.day)
            dateCell.finishClosure = { month, day in
                data.month = month
                data.day = day
            }
            cell = dateCell
            break
        case .desc:
            let descCell = tableView.dequeueReusableCell(withIdentifier: AppendCellId,
                                                         for: indexPath) as! BirthdayAppendCell
            descCell.config(with: "简介", type: .isTextField)
            descCell.textField.text = data.desc
            descCell.textFiledClosure = { desc in
                data.desc = desc
            }
            cell = descCell
            break
        }
        return cell ?? UITableViewCell()
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return datas[indexPath.row].height
    }
}
